<template>
  <n-space vertical>
    <n-space>
      <n-button
        attr-type="button"
        type="primary"
        @click="generateCode"
        :loading="generateLoading"
      >
        生成代码
      </n-button>
      <n-button attr-type="button" type="primary" @click="refreshFiles">
        刷新
      </n-button>
      <n-button
        attr-type="button"
        type="primary"
        @click="downloadMultiple"
        :disabled="!selectedFile || selectedFile.length <= 0"
      >
        批量下载
      </n-button>
    </n-space>
    <n-data-table
      :columns="columns"
      :data="data"
      :row-key="rowKey"
      :bordered="false"
      :max-height="510"
      size="small"
      @update:checked-row-keys="handleCheck"
    />
  </n-space>
  <n-modal
    v-model:show="previewModal"
    preset="dialog"
    :title="`当前预览：${previewFile?.name}`"
    :mask-closable="false"
    style="max-width: 1280px; min-width: 740px"
  >
    <n-scrollbar style="max-height: 80vh">
      <CodePreview :file="previewFile" />
    </n-scrollbar>
  </n-modal>
</template>
<script setup lang="ts">
import { h, ref, inject, Ref, watchEffect } from "vue";
import { CodeFile, Generator } from "@/types/interfaces";
import { DataTableColumns, NButton, useMessage } from "naive-ui";
import { generate, getFiles, downloadFile } from "@/utils/api";
import CodePreview from "./CodePreview.vue";
import { DB_CONNECTED_INJECT, GENERATOR_INJECT } from "@/types/constant";
// 信息提示
const message = useMessage();
// 注入生成器参数
const generator = inject(GENERATOR_INJECT) as Ref<Generator>;
// 表格列
const columns = ref<DataTableColumns<CodeFile>>([
  { type: "selection", width: 80 },
  { title: "No", key: "index", width: 80 },
  { title: "文件名称", key: "name" },
  {
    title: "操作",
    key: "actions",
    width: 300,
    render(row) {
      return [
        h(
          NButton,
          {
            attrType: "button",
            type: "primary",
            onClick: () => download(row),
          },
          {
            default: () => "下载",
          }
        ),
        h(
          NButton,
          {
            attrType: "button",
            type: "primary",
            strong: true,
            secondary: true,
            style: { marginLeft: "10px" },
            onClick: () => preview(row),
          },
          {
            default: () => "预览",
          }
        ),
      ];
    },
  },
]);
// 表格多选Key
const rowKey = (row: CodeFile) => row.index;
// 表格行数据
const data = ref<CodeFile[]>([]);
// 生成代码
const generateLoading = ref(false);
const generateCode = async () => {
  generateLoading.value = true;
  const res = await generate(generator.value);
  if (res.code != 200) {
    message.error(res.message || "生成代码失败");
    generateLoading.value = false;
    return;
  }
  generateLoading.value = false;
  refreshFiles();
};
// 刷新文件
const refreshFiles = async () => {
  const res = await getFiles();
  if (res.code !== 200) {
    message.error(res.message || "刷新文件失败");
    return;
  }
  data.value = res.data || [];
};

// 下载文件
const download = async (row: CodeFile) => {
  const res = await downloadFile([row.index]);
  if (res.code !== 200) {
    message.error(res.message || "下载失败");
  } else {
    message.success(res.message || "下载成功");
  }
};
// 选中文件
const selectedFile = ref<number[]>([]);
const handleCheck = (rowKeys: number[]) => {
  selectedFile.value = rowKeys;
};
// 批量下载文件
const downloadMultiple = async () => {
  const res = await downloadFile(selectedFile.value);
  if (res.code !== 200) {
    message.error(res.message || "下载失败");
  } else {
    message.success(res.message || "下载成功");
  }
};
// 预览文件
const previewModal = ref<boolean>(false);
const previewFile: Ref<CodeFile> = ref<CodeFile>({
  index: 0,
  name: "",
  path: "",
});
const preview = (row: CodeFile) => {
  previewModal.value = true;
  previewFile.value = row;
};
// 注入数据库连接状态
const isConnected = inject(DB_CONNECTED_INJECT) as Ref<boolean>;
watchEffect(() => {
  if (isConnected.value) {
    refreshFiles();
  } else {
    data.value = [];
  }
});
</script>
<style scoped></style>
